package com.yuyou.fn.portal.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.wens.mq.MessageHandler;
import com.github.wens.mq.RedisMessageQueue;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.*;
import com.yuyou.fn.educational.entity.*;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.educational.vo.RegClassInfoVo;
import com.yuyou.fn.educational.vo.StudentRegInfoVo;
import com.yuyou.fn.platform.entity.AreaTeam;
import com.yuyou.fn.platform.service.IAreaTeamService;
import com.yuyou.fn.portal.entity.OuterCourseClass;
import com.yuyou.fn.portal.entity.OuterCourseOrder;
import com.yuyou.fn.portal.repository.OuterCourseClassRepository;
import com.yuyou.fn.portal.repository.OuterTeacherRepository;
import com.yuyou.fn.portal.service.IOuterCourseClassService;
import com.yuyou.fn.portal.service.IOuterCourseOrderService;
import com.yuyou.fn.portal.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Field;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by wens on 2017/4/6.
 */
@Service
public class OuterCourseClassServiceImpl implements IOuterCourseClassService {

    @Resource
    private RedisMessageQueue redisMessageQueue ;

    private  HashMap<Integer,String> timeMap=new HashMap<Integer, String>();

    @Resource
    private MongoTemplate mongoTemplate;

    @Resource
    private ITeacherService teacherService ;

    @Resource
    private OuterCourseClassRepository courseClassRepository ;

    @Resource
    private IClassTimeService classTimeService;

    @Resource
    private ICustomerBindStudentService customerBindStudentService;

    @Resource
    private IStudentRegService studentRegService;

    @Resource
    private ICampusService campusService ;

    @Resource
    private ICourseClassService courseClassService;

    @Resource
    private IAreaTeamService areaTeamService;

    @Resource
    private OuterTeacherRepository outerTeacherRepository;



    @PostConstruct
    public void init(){
        timeMap.put(0,"每周日");
        timeMap.put(1,"每周一");
        timeMap.put(2,"每周二");
        timeMap.put(3,"每周三");
        timeMap.put(4,"每周四");
        timeMap.put(5,"每周五");
        timeMap.put(6,"每周六");
        redisMessageQueue.consume("course_class", "portal22", new MessageHandler() {
            @Override
            public void onMessage(byte[] bytes) {
                JSONObject jsonObject = JSONS.toJSONObject(bytes);
                String event = jsonObject.getString("event");

                if("insert".equals(event) || "update".equals(event)){
                    JSONArray rowList = jsonObject.getJSONArray("rowList");
                    List<OuterCourseClass> courseClassList = toCourseClass(rowList, false );
                    if(!courseClassList.isEmpty()){
                        courseClassRepository.save(courseClassList);
                    }

                }else if("delete".equals(event)){
                    JSONArray rowList = jsonObject.getJSONArray("rowList");
                    List<OuterCourseClass> courseClassList = toCourseClass(rowList, true );
                    courseClassRepository.delete(courseClassList);
                }
            }

            private List<OuterCourseClass> toCourseClass(JSONArray rowList , boolean isDelete) {
                List<OuterCourseClass> courseClassList = new ArrayList<>(rowList.size());
                for (int i = 0; i < rowList.size(); i++) {
                    JSONObject row = processFiled(rowList.getJSONObject(i) );
                    OuterCourseClass courseClass = row.toJavaObject(OuterCourseClass.class);
                    if(courseClass.getStatus() != 1 ){
                        continue;
                    }
                    if(!isDelete){
                        fillExtra(courseClass);
                    }
                    courseClassList.add(courseClass);
                }
                return courseClassList;
            }

            private JSONObject processFiled(JSONObject row) {
                JSONObject nRow = new JSONObject();
                for(String key : row.keySet()){
                    nRow.put(Utils.camelCase(key),row.get(key));
                }
                return nRow ;
            }
        });
    }

    private void fillExtra(OuterCourseClass outerCourseClass) {
        String[] teacherIds=outerCourseClass.getTeacherIds().split(",");
        if(teacherIds.length>0 && teacherIds[0]!=null && !"".equals(teacherIds[0])){//取第一位老师的头像存入mongodb
            String teacherId=teacherIds[0];
            String avatarUrl=teacherService.findById(Long.parseLong(teacherId)).getAvatarUrl();
            outerCourseClass.setAvatarUrl(avatarUrl);
        }
        if (outerCourseClass.getCampusId() != null) {
            Campus campus = campusService.findById(outerCourseClass.getCampusId());
            String geoLocation = campus.getGeoLocation();
            if(StringUtils.isNotEmpty(geoLocation)){
                String[] geoLocations = geoLocation.split(" ");
                if (geoLocations.length >= 2) {
                    Point point = new Point(Double.parseDouble(geoLocations[0]), Double.parseDouble(geoLocations[1]));
                    outerCourseClass.setCampusLocation(point);
                }
            }

        }

        outerCourseClass.setCampusAddress(outerCourseClass.getCampusName()+" "+outerCourseClass.getRoomName());

/*        //年级阶段
        String learningPhase=(outerCourseClass.getGradeId()+"").substring(0,1);
        outerCourseClass.setLearningPhase(learningPhase);*/

        //剩余名额
        outerCourseClass.setRemainingPlaces(outerCourseClass.getQuota()-outerCourseClass.getRegAmount());

        //计算是每天是周几
        Long class_id=outerCourseClass.getClassId();
        List<ClassTime> classTimeList=classTimeService.findClassTimeByClassId(class_id);

        //所属城市

        AreaTeam areaTeam=areaTeamService.findById(outerCourseClass.getAreaTeamId());
        outerCourseClass.setCity(areaTeam.getCity()==null?"":areaTeam.getCity());



        if(classTimeList.size()>=2){
            Date date1=classTimeList.get(0).getClassDate();
            Date date2=classTimeList.get(1).getClassDate();
            if (date1 != null && date2 != null) {
                int days = TimeUtils.daysOfTwo(date2, date1);
                if (days != 0) {
                    int i = TimeUtils.getWeekOfDate(date1);
                    outerCourseClass.setTimeInterval(timeMap.get(i));
                    if (i == 0 || i == 6) {
                        outerCourseClass.setIsWeek("1");
                    } else {
                        outerCourseClass.setIsWeek("0");
                    }
                } else {
                    outerCourseClass.setTimeInterval("每天");
                }
            }
        }
    }

    @Override
    public List<OuterCourseClass> findCourseClassByGrade(String gradeName) {
        return courseClassRepository.findByGradeName(gradeName);
    }
    @Override
    public List<OuterCourseClass> findByClassNameLike(String className,int pageNo,int pageSize) {
        PageRequest pageRequest = new PageRequest(pageNo-1,pageSize);
        return courseClassRepository.findByClassNameLike(className,pageRequest);
    }

    @Override
    public List<CourseClassResultVo> findByCondition(OuterCourseClassQueryVo outerCourseClassQueryVo, int pageNo, int pageSize){
        Criteria criteria = new Criteria();
        Query query=new Query();


        if (StringUtils.isNotEmpty(outerCourseClassQueryVo.getCampusIds())){
            String[] campusIds=outerCourseClassQueryVo.getCampusIds().split(",");
            query.addCriteria(criteria.where("campusId").in(campusIds));
        }

        if (StringUtils.isNotEmpty( outerCourseClassQueryVo.getGradeIds()) ){
            String[] gradeIds=outerCourseClassQueryVo.getGradeIds().split(",");
            List<Long> list=new ArrayList<Long>();
            for(String gradeId:gradeIds){
                list.add(Long.parseLong(gradeId));
            }
            query.addCriteria(criteria.where("gradeId").in(list));
        }

        if (StringUtils.isNotEmpty( outerCourseClassQueryVo.getGradeNames()) ){
            String[] gradeNames =outerCourseClassQueryVo.getGradeNames().split(",");
            query.addCriteria(criteria.where("gradeName").in(gradeNames));
        }

        if (StringUtils.isNotEmpty( outerCourseClassQueryVo.getSubjectIds()) ){
            String[] subjectIds=outerCourseClassQueryVo.getSubjectIds().split(",");
            List<Long> list=new ArrayList<Long>();
            for(String subjectId:subjectIds){
                list.add(Long.parseLong(subjectId));
            }
            query.addCriteria(criteria.where("gradeId").in(list));
        }

        if (StringUtils.isNotEmpty( outerCourseClassQueryVo.getSubjectName()) ){
            String[] subjectNames =outerCourseClassQueryVo.getSubjectName().split(",");
            query.addCriteria(criteria.where("subjectName").in(subjectNames));
        }


        if (StringUtils.isNotEmpty( outerCourseClassQueryVo.getCity() )){
            query.addCriteria(criteria.where("city").is(outerCourseClassQueryVo.getCity()));
        }

        if (StringUtils.isNotEmpty(  outerCourseClassQueryVo.getTimeInterval())){
            String timeInterval=outerCourseClassQueryVo.getTimeInterval();
            String[] timeIntervalList=timeInterval.split(",");
            query.addCriteria(criteria.where("timeInterval").in(timeIntervalList));
        }
        if(outerCourseClassQueryVo.getIsRecommend()!=null){
            query.addCriteria(criteria.where("isRecommend").is(outerCourseClassQueryVo.getIsRecommend()));
        }

        if(outerCourseClassQueryVo.getLongitude()!=null && outerCourseClassQueryVo.getLatitude()!=null){
            Point point=new Point(outerCourseClassQueryVo.getLongitude(),outerCourseClassQueryVo.getLatitude());
            Double distance=new Double(10000);
            if (outerCourseClassQueryVo.getDistance()!=null)
                distance=outerCourseClassQueryVo.getDistance();
            query.addCriteria(criteria.where("campusLocation").near(point).maxDistance(distance/1000/111));//公里数除以111算出弧度
        }

        if(StringUtils.isNotEmpty(  outerCourseClassQueryVo.getSeason() )){
            query.addCriteria(criteria.where("season").is(outerCourseClassQueryVo.getSeason()));
        }

        if(outerCourseClassQueryVo.getClassName()!=null &&  outerCourseClassQueryVo.getClassName()!=""){
            query.addCriteria(criteria.where("className").regex(".*?" + outerCourseClassQueryVo.getClassName() + ".*"));
        }
        if (outerCourseClassQueryVo.getTeacherIds()!=null){
            query.addCriteria(criteria.where("teacherIds").regex(".*?" +outerCourseClassQueryVo.getTeacherIds()+ ".*"));
        }

        query.addCriteria(criteria.where("status").is(1));//已开班课程
        //query.addCriteria(criteria.where("teacherIds").ne(null).andOperator(new Criteria().where("teacherIds").ne("")));//只查找有教师的课程
       //query.addCriteria(criteria.where("teacherIds").ne(""));
        return   mongoTemplate.find(query.skip(pageNo*pageSize).limit(pageSize),CourseClassResultVo.class);
    }


    @Override
    public List<OuterCourseClass> findByClassIds(List<Long> classIds) {
        Criteria criteria = new Criteria();
        return  mongoTemplate.find(new Query().addCriteria(criteria.where("classId").in(classIds)),OuterCourseClass.class);
    }

    @Override
    public OuterCourseClass findByClassId(Long classId) {
        return courseClassRepository.findByClassId(classId);
    }

    @Override
    public List<StudentCourseClassVo> findByUserId(Long userId) {
        List<CustomerBindStudent> customerBindStudentList=customerBindStudentService.findStudentsByUserIds(userId);
        if(customerBindStudentList.size()<=0){
            throw  new BusException("暂无课程信息");
        }
        List<Long> studentIdList=new ArrayList<Long>();
        for(CustomerBindStudent customerBindStudent:customerBindStudentList){
            studentIdList.add(customerBindStudent.getStudentId());
        }
        List<String> regStatusList=new ArrayList<String>();
        List<StudentReg> studentRegList=studentRegService.findStudentRegByStudentIds(studentIdList,regStatusList);
        Set<Long> classIdList=new HashSet<Long>() ;
        HashMap<Long,String> studentsNameMap=new HashMap<Long,String>();
        for (StudentReg studentReg:studentRegList){
            classIdList.add(studentReg.getClassId());
            studentsNameMap.put(studentReg.getClassId(),studentsNameMap.get(studentReg.getClassId())==null?
                    studentReg.getStudentName():studentsNameMap.get(studentReg.getClassId())+","+studentReg.getStudentName());
        }
        Query query=new Query();
        Criteria criteria = new Criteria();
        List<StudentCourseClassVo> studentCourseClassVoList=new ArrayList<StudentCourseClassVo>();
        if(classIdList.size()>0){
            query.addCriteria(criteria.where("classId").in(classIdList));
            studentCourseClassVoList=mongoTemplate.find(query,StudentCourseClassVo.class);
            for (StudentCourseClassVo studentCourseClassVo:studentCourseClassVoList){
                studentCourseClassVo.setStudentNames(studentsNameMap.get(studentCourseClassVo.getClassId()));
            }
        }


        return studentCourseClassVoList;
    }


    @Override
    public CourseClassResultVo findDetailByClassId(Long classId) {
        Criteria criteria = new Criteria();
        Query query=new Query();
        query.addCriteria(criteria.where("classId").is(classId));
        return   mongoTemplate.findOne(query,CourseClassResultVo.class);
    }


    @Override
    public List<ScheduleInfoVo> findScheduleInfoByUserIdAndDate(Long userId, String  dateString) {
        List<ScheduleInfoVo> scheduleInfoVoList=new ArrayList<ScheduleInfoVo>();
        List<CustomerBindStudent> customerBindStudentList=customerBindStudentService.findStudentsByUserIds(userId);
        List<Long> studentIdList=BeanUtils.toList(customerBindStudentList,"studentId");
        List<String> regStatusList=new ArrayList<String >();
        regStatusList.add("0");//在读
        List<StudentReg> studentRegList=studentRegService.findStudentRegByStudentIds(studentIdList,regStatusList);
        for (StudentReg studentReg : studentRegList) {
            List<ClassTime> classTimeList = classTimeService.findClassTimeByClassIdAndDateString(studentReg.getClassId(), dateString);
            for (ClassTime classTime:classTimeList){
                ScheduleInfoVo scheduleInfoVo = new ScheduleInfoVo();
                scheduleInfoVo.setStudentId(studentReg.getStudentId());
                scheduleInfoVo.setStudentName(studentReg.getStudentName());
                scheduleInfoVo.setLectureNo(classTime.getLectureNo());
                scheduleInfoVo.setStudyingTime(classTime.getStartTime()+"-"+classTime.getEndTime());
                scheduleInfoVo.setClassDate(classTime.getClassDate());
                CourseClass courseClass=courseClassService.findById(classTime.getClassId());
                scheduleInfoVo.setCampusId(courseClass.getCampusId());
                scheduleInfoVo.setCampusName(courseClass.getCampusName());
                scheduleInfoVo.setRoomId(courseClass.getRoomId());
                scheduleInfoVo.setRoomName(courseClass.getRoomName());
                scheduleInfoVo.setClassId(courseClass.getClassId());
                scheduleInfoVo.setClassName(courseClass.getClassName());
                scheduleInfoVoList.add(scheduleInfoVo);
            }
        }
        return scheduleInfoVoList;
    }
}
